import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;
import org.dbdoclet.herold.Herold;
import org.dbdoclet.option.BooleanOption;
import org.dbdoclet.option.FileOption;
import org.dbdoclet.option.Option;
import org.dbdoclet.option.OptionException;
import org.dbdoclet.option.OptionList;
import org.dbdoclet.option.SelectOption;
import org.dbdoclet.option.StringOption;
import org.dbdoclet.parser.ParserException;
import org.dbdoclet.tokenizer.TokenizerException;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.mozilla.interfaces.nsIDOMHTMLCollection;
import org.mozilla.interfaces.nsIDOMHTMLDocument;
import org.pyxx.dl.conv.docbook2scorm;

/**
 * Contain the skeleton of converting HTMLs to SCORM
 */
public class SaveScromAdaptor extends SelectionAdapter {
	private static final File USER_DIR = new File(System.getProperty("user.dir"));
	private static final File etcDir = new File(USER_DIR, "../res/etc");
	private final URL url;
	private final nsIDOMHTMLDocument htmlDoc;

	public SaveScromAdaptor(URL url, nsIDOMHTMLDocument htmlDoc) {
		super();
		this.url = url;
		this.htmlDoc = htmlDoc;
	}

	/**
	 * Convert the HTML to DOCBook then SCORM
	 */
	public void widgetSelected(SelectionEvent e) {
		try {
			FileUtils.cleanDirectory(USER_DIR);
			final nsIDOMHTMLCollection list = htmlDoc.getLinks();
			final List<String> links = new ArrayList<String>();
			for (int i = 0; i < list.getLength(); i++) {
				final String nodeValue = list.item(i).getAttributes().getNamedItem("href").getNodeValue();
				if (!nodeValue.contains("://")) {
					final String link = url.getProtocol() + "://" + url.getHost() + "/forum/" + nodeValue;
					links.add(link);
				}
			}
			final File output = toDocBook(links);
			docbook2scorm.manifest(output, etcDir);

			// Check saxon documents for detail of the parameters
			final String args[] = new String[] { "-x", "org.apache.xml.resolver.tools.ResolvingXMLReader", "-y",
					"org.apache.xml.resolver.tools.ResolvingXMLReader", "-r",
					"org.apache.xml.resolver.tools.CatalogResolver", "-o",
					new File(output.getParent(), "index.html").getAbsolutePath(),
					new File(output.getParent(), docbook2scorm.SOURCE_XML).getAbsolutePath(),
					USER_DIR.getParent() + "/res/docbook-xsl-1.69.1/html/chunk.xsl", "use.extensions=1",
					"character-representation=native", "chunker.output.encoding=utf-8", "default.encoding=utf-8",
					"htmlhelp.encoding=utf-8", "glossentry.show.acronym=yes", "generate.section.toc.level=3",
					"toc.section.depth=3", "ulink.target=_blank", "generate.manifest=0", "chunk.section.depth=2",
					"chunk.first.sections=1", "html.stylesheet=style.css", "navig.showtitles=0",
					"suppress.navigation=1", "suppress.navigation=1", "section.autolabel=1",
					"section.label.includes.component.label=1" };
			com.icl.saxon.StyleSheet.main(args);

			// copy external resolves and zip the content as package.
			final Project project = new Project();
			copyresources(project);
			copyschemas(project);
			final Zip zip = new Zip();
			zip.setProject(project);
			zip.setDestFile(new File("../scorm.zip"));
			zip.setBasedir(USER_DIR);
			zip.execute();
		} catch (Exception e1) {
			throw new RuntimeException(e1);
		}
	}

	private Copy copyschemas(final Project project) {
		final Copy copy = new Copy();
		copy.setProject(project);
		copy.setTodir(USER_DIR);
		final FileSet from = new FileSet();
		from.setDir(etcDir);
		copy.addFileset(from);
		copy.execute();
		return copy;
	}

	private Copy copyresources(final Project project) {
		final Copy copy = new Copy();
		copy.setProject(project);
		copy.setTodir(USER_DIR);
		final FileSet from = new FileSet();
		from.setDir(new File(USER_DIR.getParentFile() + "/res/sample/resources"));
		copy.addFileset(from);
		copy.execute();
		return copy;
	}

	/**
	 * 
	 * Setup the default parameters and call the API to convert the HTML to docbook
	 * 
	 * @param links
	 * @return
	 * @throws IOException
	 * @throws OptionException
	 * @throws ParserConfigurationException
	 * @throws ParserException
	 * @throws TokenizerException
	 */
	public static File toDocBook(final List<String> links) throws IOException, OptionException,
			ParserConfigurationException, ParserException, TokenizerException {
		// refer to the dbdoclet and check the detail of the parameters meaning
		final ArrayList<String> inList = new ArrayList<String>();
		final OptionList options = new OptionList(new String[0]);
		Option option = new StringOption("destination-encoding", "d");
		option.setDefault("UTF-8");
		options.add(option);
		option = new BooleanOption();
		option.setLongName("no-prolog");
		option.setDefault("false");
		options.add(option);
		option = new BooleanOption("no-tables", "T");
		option.setDefault("false");
		options.add(option);
		SelectOption selopt = new SelectOption("log-level", "l");
		String optv1[] = { "error", "warn", "info", "debug" };
		selopt.setList(optv1);
		selopt.setDefault("debug");
		options.add(selopt);
		option = new FileOption("out", "o");
		final File output = new File(USER_DIR, "docbook.xml");
		option.setDefault(output.getAbsolutePath());
		options.add(option);
		selopt = new SelectOption("root-element", "r");
		String optv2[] = { "article", "book" };
		selopt.setList(optv2);
		selopt.setDefault("article");
		options.add(selopt);
		option = new StringOption("source-encoding", "s");
		option.setDefault("Big5");
		options.add(option);
		option = new StringOption("sysid", "y");
		option.setDefault("http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd");
		options.add(option);
		option = new StringOption("title", "t");
		option.setDefault("http://www.dbdoclet.org/herold");
		options.add(option);
		if (!options.validate())
			throw new OptionException(options.getError());

		// Copy the HTML to local files
		for (Iterator<String> iterator = links.iterator(); iterator.hasNext();) {
			final String link = iterator.next();
			final File file = new File(USER_DIR, link.substring(link.lastIndexOf('/')).replace("?", "_"));
			try {
				file.createNewFile();
				final InputStream input = new URL(link).openStream();
				IOUtils.copy(input, new FileOutputStream(file));
				inList.add(file.getAbsolutePath());
			} catch (Exception e) {
				System.err.println(file.getAbsolutePath());
				e.printStackTrace();
			}
		}
		final Herold converter = new Herold();
		if (converter.convert(inList, options) != 0)
			throw new RuntimeException("XML is not valid");
		return output;
	}

}